import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONConfig;
import cn.hutool.json.JSONUtil;

import java.util.*;
import java.util.stream.Collectors;


public class TreeFromList {
    public static void main(String[] args) {
        List<String> initialList = List.of(
                "web", "web-dept", "web-dept-info",
                "web-city", "web-city-level", "web-city-test","web-city-test-aaa","web-city-test-bbb","web-city-test-ccc",
                "web-head", "web-head-info", "web-head-content",
                "h5", "h5-intro", "h5-tree",
                 "sdsp-gateway", "sdsp-common",
                "sdsp-common-api", "sdsp-common-core", "sdsp-auth",
                "manager", "manager-dept", "manager-dept-info"
        );

        List<TreeNode> nodeList = new ArrayList<>(initialList.size());
        for (String name : initialList) {
            nodeList.add(new TreeNode(name));
        }

        TreeNode root = new TreeNode("ROOT");
        root.children = nodeList;

        root.children = build(root.getChildren());

        JSONConfig jsonConfig = new JSONConfig();
        jsonConfig.setIgnoreNullValue(true);
        System.out.println("result = " + JSONUtil.toJsonPrettyStr(root));
    }

    public static List<TreeNode> build(List<TreeNode> nodeList) {
        if (CollUtil.isEmpty(nodeList)) {
            return null;
        }
        boolean flag = false;
        List<TreeNode> treeNodes = new ArrayList<>(nodeList);
        List<TreeNode> names = new ArrayList<>(nodeList);
        Iterator<TreeNode> iterator = treeNodes.iterator();
        while (iterator.hasNext()) {
            TreeNode node = iterator.next();
            List<TreeNode> children = names.stream().filter(n ->
                            !n.getValue().equals(node.getValue())
                                    && n.getValue().startsWith(node.getValue()))
                    .collect(Collectors.toList());
            if (!CollUtil.isEmpty(children)) {
                names.removeAll(children);
                node.children = children;
                flag = true;
            }
        }

        List<String> values = names.stream().map(treeNode -> treeNode.getValue()).collect(Collectors.toList());

        List<TreeNode> result = treeNodes.stream().filter(treeNode -> values.contains(treeNode.getValue())).collect(Collectors.toList());

        result.forEach(node -> {
            node.children = build(node.getChildren());
        });
        return result;
    }
}
